package com.heima.springai.repository.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.heima.springai.entity.po.ChatHistory;
import com.heima.springai.mapper.ChatHistoryMapper;
import com.heima.springai.repository.IChatHistoryService;
import com.heima.springai.entity.vo.MessageVo;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.heima.springai.untils.RedisConstant.CHAT_HISTORY_CHAT_ID;

/**
 * @author 噤玥
 */
@Service
public class ChatHistoryServiceImpl extends ServiceImpl<ChatHistoryMapper, ChatHistory> implements IChatHistoryService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveIdList(String chatId, String type) {
        String key = CHAT_HISTORY_CHAT_ID+ type;
        Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, chatId);
        if (Boolean.TRUE.equals(isMember)) {
            return;
        }
        ChatHistory chatHistory = new ChatHistory();
        chatHistory.setChatId(chatId);
        chatHistory.setType(type);
        save(chatHistory);
        stringRedisTemplate.opsForSet().add(key, chatId);
    }

    @Override
    public List<String> getIdList(String type) {
        Set<String> members = stringRedisTemplate.opsForSet().members(CHAT_HISTORY_CHAT_ID + type);
        if (members != null) {
            return members.stream().toList();
        }
        List<ChatHistory> history = list(new QueryWrapper<ChatHistory>().eq("type", type));
        return history.stream()
                .map(ChatHistory::getChatId)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveHistoryMessages(List<MessageVo> list, String chatId, String type) throws JsonProcessingException {
        if (list.isEmpty()){
            return;
        }
        ChatHistory chatHistory = getOne(new QueryWrapper<ChatHistory>().eq("chat_id", chatId).eq("type", type));
        if (chatHistory == null) {
            return;
        }
        String historyMessages = chatHistory.getHistoryMessages();
        ObjectMapper mapper = new ObjectMapper();
        List<MessageVo> messageVos = mapper.readValue(historyMessages, new TypeReference<List<MessageVo>>() {});
        messageVos.addAll(list);
        String updatedJson = mapper.writeValueAsString(messageVos);
        chatHistory.setHistoryMessages(updatedJson);
        updateById(chatHistory);
    }

    @Override
    public List<MessageVo> getHistoryMessages(String chatId, String type) throws JsonProcessingException {
        ChatHistory chatHistory = getOne(new QueryWrapper<ChatHistory>().eq("chat_id", chatId).eq("type", type));
        if (chatHistory != null) {
            String json = chatHistory.getHistoryMessages();
            if (json != null) {
                ObjectMapper mapper = new ObjectMapper();
                return mapper.readValue(json, new TypeReference<List<MessageVo>>() {});
            }
        }
        return List.of();
    }

}